﻿using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using Bridge.Objects;
using Bridge.Properties;
using Microsoft.Win32;

namespace Bridge.UI
{
    /// <summary>
    /// Interaction logic for DLLManager.xaml
    /// </summary>
    public partial class DLLManager : UserControl
    {
        public static readonly RoutedEvent DLLLoadedEvent = EventManager.RegisterRoutedEvent(
            "DLLLoaded",
            RoutingStrategy.Bubble,
            typeof(RoutedEventHandler),
            typeof(DLLManager));

        public DLLManager()
        {
            InitializeComponent();

            Main.AssembliesReloaded += new EventHandler(Main_AssembliesReloaded);
        }

        public event RoutedEventHandler DLLLoaded
        {
            add { AddHandler(DLLLoadedEvent, value); }
            remove { RemoveHandler(DLLLoadedEvent, value); }
        }


        private void ReloadAssemblies()
        {
            listBoxDLLs.ItemsSource = Settings.Default.DLLPaths;
        }

        private void RaiseDLLLoadedEvent(string dll)
        {
            RaiseEvent(new RoutedEventArgs(DLLLoadedEvent, dll));
        }

        private void buttonLoadNew_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog()
            {
                CheckFileExists = true,
                DefaultExt = "bpkg",
                Multiselect = false,
                Filter = "Bridge Packages (*.bpkg)|*.bpkg|DLL Files (*.dll)|*.dll|All Files|*.*"
            };
            if (openFileDialog.ShowDialog() == true)
            {
                if (File.Exists(openFileDialog.FileName) && !Settings.Default.DLLPaths.Contains(openFileDialog.FileName))
                {
                    try
                    {
                        if (Main.LoadFile(openFileDialog.FileName))
                        {
                            Settings.Default.DLLPaths.Add(openFileDialog.FileName);
                            Settings.Default.Save();
                            Main.OnAssembliesReloaded();
                            WarningWindow.ShowDialog(WarningWindow.WarningType.OK, string.Format("Package/DLL {0} successfully loaded.", openFileDialog.FileName), null, "DLL Loaded");
                            listBoxDLLs.ItemsSource = null;
                            listBoxDLLs.ItemsSource = Settings.Default.DLLPaths;
                            Log.MetricsLog.InfoFormat("Added {0}", Path.GetFileName(openFileDialog.FileName));
                        }
                    }
                    catch (FileLoadException ex)
                    {
                        Log.NormalLog.Warn(string.Format("User tried to load {0}, but failed.", openFileDialog.FileName), ex);
                        WarningWindow.ShowDialog(WarningWindow.WarningType.OK, string.Format("Loading DLL {0} failed. Check to make sure the file is not corrupt. If you downloaded this file from the internet, try redownloading it.", openFileDialog.FileName), ex.ToString());
                    }
                    catch (FileNotFoundException ex)
                    {
                        Log.NormalLog.Warn(string.Format("User tried to load {0}, but it was not found.", openFileDialog.FileName), ex);
                        WarningWindow.ShowDialog(WarningWindow.WarningType.OK, string.Format("Loading DLL {0} failed. Check to make sure the file exists.", openFileDialog.FileName), ex.ToString());
                    }
                    catch (BadImageFormatException ex)
                    {
                        Log.NormalLog.Warn(string.Format("User tried to load {0}, but failed.", openFileDialog.FileName), ex);
                        WarningWindow.ShowDialog(WarningWindow.WarningType.OK, string.Format("Loading DLL {0} failed. Check to make sure the file is a loadable C# DLL. If you downloaded this file from the internet, try redownloading it.", openFileDialog.FileName), ex.ToString());
                    }
                }
            }

        }

        private void buttonUnloadSelected_Click(object sender, RoutedEventArgs e)
        {
            if (listBoxDLLs.SelectedItem != null)
            {
                foreach (string item in listBoxDLLs.SelectedItems)
                {
                    if (Settings.Default.DLLPaths.Contains(item))
                    {
                        Settings.Default.DLLPaths.Remove(item);
                    }
                }
                Settings.Default.Save();
                WarningWindow.ShowDialog(WarningWindow.WarningType.OK, "Selected DLLs will not be loaded on the next run of the program.");
            }
        }

        private void Main_AssembliesReloaded(object sender, EventArgs e)
        {
            ReloadAssemblies();
        }


    }
}
